"""
Anthropic Claude API提供商实现
基于组合模式设计
"""
import time
import logging
from typing import Dict, Any, List, Optional, Generator

# 设置日志
logger = logging.getLogger("connllm.anthropic")

# 导入基础组件
from .provider import BaseProvider

class AnthropicProvider(BaseProvider):
	"""Anthropic Claude API提供商"""
	
	def __init__(self, config: Dict[str, Any]):
		"""
		初始化Anthropic提供商
		
		Args:
			config: 配置字典
		"""
		# 保存特有配置，在调用父类初始化前
		self.tools_enabled = config.get("tools", False)
		self.anthropic_version = config.get("anthropic_version", "2023-06-01")
		
		# 调用父类初始化
		super().__init__(config)
		
		# 初始化客户端
		self._setup_client()
		
	def _setup_client(self) -> None:
		"""设置Anthropic客户端"""
		try:
			import anthropic
			self.client = anthropic.Anthropic(api_key=self.config_manager.get("api_key"))
			self.has_sdk = True
			logger.debug("已成功初始化Anthropic SDK客户端")
		except ImportError as e:
			logger.warning(f"未安装anthropic SDK，将使用HTTP客户端: {str(e)}")
			self.client = None
			self.has_sdk = False
			
	def _get_default_headers(self) -> Dict[str, str]:
		"""获取默认HTTP头"""
		headers = super()._get_default_headers()
		
		# Anthropic特有头
		api_key = self.config_manager.get("api_key", "")
		headers.update({
			"x-api-key": api_key,
			"anthropic-version": self.anthropic_version,
		})
		
		return headers
		
	def _init_capabilities(self) -> None:
		"""初始化Anthropic支持的功能组件"""
		try:
			# 导入能力实现
			from ..implementations.anthropic.streaming import AnthropicStreaming
			from ..implementations.anthropic.partial_mode import AnthropicPartialMode
			
			# 添加流式输出功能
			self.capability_manager.register("streaming", AnthropicStreaming)
			
			# 添加部分输出功能
			self.capability_manager.register("partial_mode", AnthropicPartialMode)
			
			# 添加工具调用功能（如果配置中启用）
			if self.tools_enabled:
				try:
					from ..implementations.anthropic.tool_call import AnthropicToolCall
					self.capability_manager.register("tool_calls", AnthropicToolCall)
					logger.debug("已注册Anthropic工具调用功能")
				except ImportError as e:
					logger.warning(f"Anthropic工具调用功能注册失败: {str(e)}")
					
		except ImportError as e:
			logger.warning(f"导入Anthropic能力实现失败: {str(e)}")
	
	def _complete_internal(self, messages: List[Dict[str, Any]]) -> Any:
		"""
		内部完成方法实现
		
		Args:
			messages: 消息列表
			
		Returns:
			API响应
		"""
		start_time = time.time()
		
		try:
			# 准备请求参数
			params = self._prepare_request_params(messages)
			
			# 添加工具（如果有）
			if self.tools_enabled and self.capability_manager.has("tool_calls"):
				tool_call = self.capability_manager.get("tool_calls")
				params = tool_call.prepare_request(params)
				
			# 选择请求方式
			if self.has_sdk and self.client:
				# 使用SDK
				response = self.client.messages.create(**params)
				return response
			else:
				# 使用HTTP客户端
				response = self.http_client.request(
					method="POST",
					endpoint="/v1/messages",
					data=params
				)
				return response.json()
				
		except Exception as e:
			elapsed = time.time() - start_time
			logger.error(f"Anthropic请求失败，耗时: {elapsed:.2f}秒，错误: {str(e)}")
			raise e
			
		finally:
			elapsed = time.time() - start_time
			if elapsed > 1.0:  # 只记录耗时超过1秒的请求
				logger.debug(f"Anthropic请求完成，耗时: {elapsed:.2f}秒")
	
	def _prepare_request_params(self, messages: List[Dict[str, Any]]) -> Dict[str, Any]:
		"""
		准备API请求参数
		
		Args:
			messages: 消息列表
			
		Returns:
			请求参数字典
		"""
		# 获取完成设置
		completion_settings = self.config_manager.get_completion_settings()
		
		return {
			"model": self.model,
			"messages": messages,
			"max_tokens": completion_settings.get("max_tokens", 4096),
			"temperature": completion_settings.get("temperature", 0.7),
			"top_p": completion_settings.get("top_p", 1.0),
			"stream": False  # 非流式模式
		}
		
	def _extract_text_from_response(self, response: Any) -> str:
		"""
		从响应中提取文本
		
		Args:
			response: 响应数据
			
		Returns:
			提取的文本
		"""
		# 处理SDK响应对象
		if hasattr(response, "content") and not isinstance(response, dict):
			# 如果是SDK响应对象，转换为字典
			try:
				response_dict = response.model_dump()
				return self._extract_text_from_dict(response_dict)
			except AttributeError:
				# 旧版SDK可能没有model_dump方法
				try:
					import json
					response_dict = json.loads(json.dumps(response, default=lambda o: o.__dict__))
					return self._extract_text_from_dict(response_dict)
				except Exception as e:
					logger.warning(f"无法序列化SDK响应对象: {str(e)}")
					# 尝试直接访问content属性
					if hasattr(response, "content"):
						content = response.content
						if isinstance(content, list):
							return "".join(item.text for item in content if getattr(item, "type", None) == "text")
						return str(content)
						
		# 处理字典响应
		if isinstance(response, dict):
			return self._extract_text_from_dict(response)
			
		# 其他类型，使用父类方法
		return super()._extract_text_from_response(response)
		
	def _extract_text_from_dict(self, response: Dict[str, Any]) -> str:
		"""
		从字典响应中提取文本
		
		Args:
			response: 响应字典
			
		Returns:
			提取的文本
		"""
		# Claude 3风格
		if "content" in response:
			if isinstance(response["content"], str):
				return response["content"]
			elif isinstance(response["content"], list):
				# 提取text类型的内容
				text_parts = []
				for content_item in response["content"]:
					if content_item.get("type") == "text":
						text_parts.append(content_item.get("text", ""))
				return "".join(text_parts)
		
		# 旧版Claude风格			
		if "completion" in response:
			return response["completion"]
			
		# 无法提取，使用父类方法
		return super()._extract_text_from_response(response)
